package com.mxj.web;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.core.Local;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;
import java.security.Principal;
import java.time.ZoneId;
import java.util.Map;
import java.util.TimeZone;

/**
 * @author yuisama
 * @date 2023/02/09 00:30
 **/
@Slf4j
//使用这个注解，就可以不用注入OutputStream  进行输入输出
@Controller
@RequestMapping("/method-arguments")
public class AboutMethodArgumentController {
    //点击网址，然后选择webServlet,然后选择1.3.3的Method arguments
    @GetMapping("/hello")
    public void hello(
            WebRequest webRequest,
            NativeWebRequest nativeWebRequest,
            ServletRequest servletRequest,
            ServletResponse servletResponse,
            HttpSession httpSession,
            PushBuilder pushBuilder,
            HttpMethod httpMethod,
            Local local,
            TimeZone timeZone,
            ZoneId zoneId,
            InputStream inputStream,
            OutputStream outputStream
            //Writer writer,
//            Map<String,Object> map,
//            Model model,
//            ModelMap modelMap,
//            RedirectAttributes redirectAttributes
    )
    {
        log.info("随便的啥");
    }

    @RequestMapping("/method2")
    public void method2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //和之前学过的Servlet一样，根据请求，填充响应
        req.setCharacterEncoding("utf-8");
        String target = req.getParameter("target");
        log.info("接下来是debug");
        log.debug("请求参数中的target = "+ target);
        if(target != null){
            target = target.trim();//去掉前后的空格
        }
        if(target == null || target.isEmpty()){
            target = "门门";
        }
        String message = target + "你好呀";

        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/plain");//纯文本输出
        resp.getWriter().println(message);
    }

    //相比较Servlet版本，可以更简化一些
    @RequestMapping(value = "/method3",produces = "text/plain; charset=utf-8")
    //这里的produces  就是将响应头中的 Content-type设置好了
    @ResponseBody
    //整个方法使用responseBody修饰，意思是整个方法会完整的返回响应体
    public String method3(@RequestParam(value = "target",defaultValue = "世界") String target){
        //接受一个target参数，如果没有传递参数，那么默认值是 世界
        log.debug("请求参数中的 target =" +target);
        return "你好3" + target;
        //返回String类型就是完整的响应体
    }


    //3.前后端分离的模式，直接返回JSON
    @Data
    static class Dog {
        public final String name;
        public final int age;
    }

    @GetMapping("/method4")
    @ResponseBody
    //这里responseBody注解，什么都没加，返回的对象会被JSON序列化输出
    public Dog createDog(){
        return new Dog("黑仔",3);
    }


    //当变量名和请求参数同名时，可以省略@RequestParam注解
    @GetMapping("/method5")
    @ResponseBody
    public Dog createDog2(String name,String age){
        log.info("请求参数 name = "+name);
        log.info("请求参数 age = "+age);

        int ageInt = Integer.parseInt(age);
        return new Dog(name,ageInt);
    }


    //让Spring,帮我们把age从String 转为Int
    //风险是如果 age 无法转为int,会出现400异常
    @GetMapping("/method6")
    @ResponseBody
    public Dog createDog3(String name,int age){
        log.info("请求参数 name = "+name);
        log.info("请求参数 age = "+age);
        return new Dog(name,age);
    }

    //如果参数比较多，甚至可以放在对象中完成
    @GetMapping("/method7")
    @ResponseBody
    public Dog createDog4(Dog dog){
        log.info("method7: 请求参数 :"+dog);
        return dog;
    }
}

